#
# Created by Gerikes for GerikSpells
#

import CvUtil
from CvPythonExtensions import *
from GerikSpells import GerikSpellBase
import GerikSpellsInterface

gc = CyGlobalContext()

from GSGraphicsPolicies import GSPlot as GSPlotGraphics
from GSGraphicsPolicies import GSPieMenu as GSPieMenuGraphics

from GSTargetInfoPolicies import GSNoTarget
from GSTargetInfoPolicies import GSSinglePlotTarget

import GerikSpellsUtils
import copy # To make copies of the prototype target policies

class GSBase:
    def __init__(self):
        pass
    
    def start(self, bAlt, bShift, bCtrl):
        raise NotImplementedError

class GSImmediate(GSBase):
    def __init__(self):
        GSBase.__init__(self)
    
    def start(self, bAlt, bShift, bCtrl):
        self.castSpell(GSNoTarget())

#
# A base class for policies that use a graphical targetting system
#
class GSTargetting(GSBase):
    def __init__(self, pPolicyPairList):
        GSBase.__init__(self)

        self.m_pTargetPolicyList = []
        self.m_pGraphicsPolicyList = []
        self.m_pTargetInfoResults = []
        self.m_iNumberOfStages = 0

        for tPair in pPolicyPairList:
            self.m_pTargetPolicyList.append(tPair[0])
            self.m_pGraphicsPolicyList.append(tPair[1])
            self.m_pTargetInfoResults.append(None)
            self.m_iNumberOfStages += 1

        self.m_iStage = 0
        self.m_pCurrentGraphicsPolicy = None

    def getGraphicsPolicy(self):
        return self.m_pCurrentGraphicsPolicy

    def setGraphicsPolicy(self, pNewPolicy):
        self.m_pCurrentGraphicsPolicy = pNewPolicy

    def getTargettingResults(self, iStage):
        return self.m_pTargetInfoResults[iStage]

    def start(self, bAlt, bShift, bCtrl):
        GerikSpellsInterface.setLocalInterfaceMode1()
        self.m_iStage = 0
        self.setGraphicsPolicy(self.m_pGraphicsPolicyList[0])

        # Builds the range list for this stage.
        pRangePlotList = []
        if (self.m_pTargetPolicyList[0].getRangeMakerCallback()):
            pRangePlotList = self.m_pTargetPolicyList[0].getRangeMakerCallback()(self.getCastingPlot())
        self.getGraphicsPolicy().start(self.m_pTargetPolicyList[0], self.handleInput, pRangePlotList)


    def stop(self):
        gp = self.getGraphicsPolicy()
        if (gp):
            gp.stop()
        self.setGraphicsPolicy(None)

    def handleInput(self, pSelectedTargetInfo):
        if (pSelectedTargetInfo.isCurrentTargetValid(self.getCastingGroup(), self.getCastingPlot())):

            # Save the target.
            self.m_pTargetInfoResults[self.m_iStage] = pSelectedTargetInfo

            # Close the stage, and progress
            self.getGraphicsPolicy().stop()
            self.m_iStage += 1

            # If we still have more stages to go:
            if (self.m_iStage < self.m_iNumberOfStages):
                pCastGroup = self.getCastingGroup()
                pCastPlot = self.getCastingPlot()

                if (self.m_pTargetPolicyList[self.m_iStage].isPlotTargetPolicy()):
                    # Plots don't have pre-defined targets built in, so the target info doesn't need to be created.
                    GerikSpellsInterface.setLocalInterfaceMode2()
                    self.setGraphicsPolicy(self.m_pGraphicsPolicyList[self.m_iStage])
                    self.getGraphicsPolicy().start(self.m_pTargetPolicyList[0], self.handleInput, None)
                else:
                    # Get the list of targettable items.
                    pTotalTargetTuple = pSelectedTargetInfo.getSecondaryTargetList(pCastGroup, pCastPlot)
                    pTargetList = self.m_pTargetPolicyList[self.m_iStage].getTargettableList(pCastGroup, pCastPlot, pTotalTargetTuple[0])
                    pTargetList.extend(self.m_pTargetPolicyList[self.m_iStage].getTargettableList(pCastGroup, pCastPlot, pTotalTargetTuple[1]))

                    pTargetInfoList = []

                    for pTarget in pTargetList:
                        pTargetInfo = copy.copy(self.m_pTargetPolicyList[self.m_iStage])
                        pTargetInfo.setTarget(pTarget)
                        pTargetInfoList.append(pTargetInfo)

                    # Set the interface mode and graphics policy, then start the graphics policy.
                    GerikSpellsInterface.setLocalInterfaceMode2()
                    self.setGraphicsPolicy(self.m_pGraphicsPolicyList[self.m_iStage])
                    self.getGraphicsPolicy().start(self.m_pTargetPolicyList[0], self.handleInput, pTargetInfoList)
                    
            else:
                self.castSpell(pSelectedTargetInfo)
        else:
            CvUtil.pyPrint("Warning: Cancelled handling input due to selected target not being targettable")

